package cc.magicjson.scenario.implement.module.jdbc.template.controller;

import cc.magicjson.scenario.implement.module.jdbc.template.entity.User;
import cc.magicjson.scenario.implement.module.jdbc.template.manager.BatchOperations;
import cc.magicjson.scenario.implement.module.jdbc.template.response.BatchOperationResult;
import cc.magicjson.scenario.implement.module.jdbc.template.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/users")
@Slf4j
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;

    @GetMapping("/users")
    public ResponseEntity<List<User>> findAll() {
        return ResponseEntity.ok(userService.findAll());
    }

    @GetMapping("/user/{id}")
    public ResponseEntity<User> findById(@PathVariable("id") Integer id) {
        return ResponseEntity.ok(userService.findById(id));
    }

    @PostMapping("/batch")
    public ResponseEntity<BatchOperationResult> batchOperation(
        @RequestParam("operation") String operation) {
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 30000; i++) {
            User user = new User();
//            user.setId(Long.valueOf(i));
            user.setEmail("user" + i + "@example.com");
            user.setName("User" + i);
            users.add(user);
        }
        List<User> users1 = new ArrayList<>();
        if("update".equals(operation)){
            for (int i = 0; i < 3000; i++) {
                User user = new User();
                user.setId(Long.valueOf(i));
                user.setEmail("user1" + i + "@example.com");
                user.setName("User1" + i);
                users1.add(user);
            }
        }
        try {
            int affectedRows = switch (operation.toLowerCase()) {
                case "insert" -> userService.batchInsert(users);
                case "update" -> userService.batchUpdate(users1);
                case "upsert" -> userService.batchUpsert(users);
                case "large-insert" -> userService.batchInsertLarge(users);
                default -> throw new IllegalArgumentException(
                    "Unsupported operation: " + operation);
            };

            return ResponseEntity.ok(BatchOperationResult.success(
                String.format("Batch %s completed. Affected rows: %d",
                    operation, affectedRows),
                affectedRows
            ));

        } catch (Exception e) {
            log.error("Batch operation failed", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(BatchOperationResult.failure(e.getMessage(), e));
        }
    }

    @GetMapping("/concurrent-test")
    public ResponseEntity<String> testConcurrentConnections() {
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch latch = new CountDownLatch(5);  // 5个并发请求

        // 提交多个并发任务
        for (int i = 0; i < 5; i++) {
            executorService.submit(() -> {
                try {
                    // 模拟长时间运行的查询
                    List<User> users = userService.findAll();
                    Thread.sleep(2000); // 保持连接2秒
                    log.info("Query completed, found {} users", users.size());
                } catch (Exception e) {
                    log.error("Error in concurrent test", e);
                } finally {
                    latch.countDown();
                }
            });
        }

        try {
            // 等待所有任务完成
            latch.await(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            executorService.shutdown();
        }

        return ResponseEntity.ok("Concurrent test completed");
    }

    // 添加一个慢查询接口用于测试
    @GetMapping("/slow-query")
    public ResponseEntity<List<User>> slowQuery() {
        try {
            Thread.sleep(3000); // 模拟慢查询
            return ResponseEntity.ok(userService.findAll());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @Autowired
    @Qualifier("otherJdbcTemplate")
    private BatchOperations batchOperations;
    @EventListener(ContextRefreshedEvent.class)
    public void listener(ContextRefreshedEvent event){
        System.out.println(batchOperations.getJdbcTemplate());
    }
}
